//
//  ZoomTransition.m
//  ZoomSegueExample
//
//  Created by Denys Telezhkin on 29.06.14.
//
//  Copyright (c) 2014 Denys Telezhkin
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//  SOFTWARE.

#import "ZoomInteractiveTransition.h"
#import "UIView+Snapshotting.h"
#import "ZMYReadViewController.h"
#import "BookrackCollectionViewController.h"
@interface ZoomInteractiveTransition()

@property (nonatomic, assign) CGFloat startScale;
@property (nonatomic, assign) UINavigationControllerOperation operation;
@property (nonatomic, assign) BOOL shouldCompleteTransition;
@property (nonatomic, assign, getter = isInteractive) BOOL interactive;
@end

@implementation ZoomInteractiveTransition
-(void)commonSetup
{
    self.transitionDuration = 0.8;
    self.handleEdgePanBackGesture = YES;
    self.transitionAnimationOption = UIViewKeyframeAnimationOptionCalculationModeCubic;
}

- (instancetype)initWithNavigationController:(UINavigationController *)nc
{
    if (self = [super init]) {
        self.navigationController = nc;
        nc.delegate = self;
        [self commonSetup];
    }
    return self;
}

-(instancetype)init
{
    if (self = [super init])
    {
        [self commonSetup];
    }
    return self;
}

#pragma mark - UIViewControllerAnimatedTransitioning

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return self.transitionDuration;
}

-(UIImageView *)initialZoomSnapshotFromView:(UIView *)sourceView
                            destinationView:(UIView *)destinationView
{
    
    UIImage * fromSnapshot = [sourceView dt_takeSnapshot];
    UIImage * toSnapshot = [destinationView dt_takeSnapshot];
    
    UIImage * animateSnapshot = toSnapshot;
    if (fromSnapshot.size.width>toSnapshot.size.width)
    {
        animateSnapshot = fromSnapshot;
    }
    UIImageView * sourceImageView = [[UIImageView alloc] initWithImage:animateSnapshot];
    sourceImageView.contentMode = UIViewContentModeScaleToFill;
    
    return sourceImageView;
}

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIView *containerView = [transitionContext containerView];
    UIViewController <ZoomTransitionProtocol> * fromVC = (id)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController <ZoomTransitionProtocol> *toVC = (id)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    UIView * fromView = [fromVC view];
    UIView * toView = [toVC view];
    UIView * firstFromView = [fromVC viewForZoomTransition];
    UIView * firstToView = [toVC viewForZoomTransition];
    UIView * secondFromView = [fromVC secondViewForZoomTransition];
    UIView * secondToView = [toVC secondViewForZoomTransition];
    firstFromView.alpha = 1;
    UIImageView * animatingImageView1 = [self initialZoomSnapshotFromView:secondFromView
                                                          destinationView:secondToView];
    animatingImageView1.frame = [secondFromView.superview convertRect:secondFromView.frame
                                                               toView:containerView];
    [containerView addSubview:animatingImageView1];
    
    UIImageView * animatingImageView2 = [self initialZoomSnapshotFromView:firstFromView
                                                          destinationView:firstToView];
    animatingImageView2.frame = [firstFromView.superview convertRect:firstFromView.frame
                                                              toView:containerView];
    [containerView addSubview:animatingImageView2];
    
    CATransform3D transformblank;
    if (self.operation == UINavigationControllerOperationPush) {
        [containerView insertSubview:toVC.view aboveSubview:fromVC.view];
        fromView.alpha = 1;
        toView.alpha = 0;
        secondFromView.alpha = 1;
        secondToView.alpha = 0;
        transformblank = CATransform3DMakeRotation(-M_PI_2 / 1.01, 0.0, 1.0, 0.0);
        animatingImageView2.layer.anchorPoint = CGPointMake(0, 0.5);
        animatingImageView2.frame = animatingImageView1.frame;
        animatingImageView2.opaque = YES;
    } else {
        fromView.alpha = 0;
        toView.alpha = 1;
        secondFromView.alpha = 0;
        secondToView.alpha = 1;
        [containerView insertSubview:toVC.view belowSubview:fromVC.view];
        transformblank = CATransform3DMakeRotation(-M_PI_2 / 1.01, 0.0, 1.0, 0.0);
        animatingImageView2.layer.anchorPoint = CGPointMake(0, 0.5);
        animatingImageView2.center = CGPointMake(0, animatingImageView1.bounds.size.height/2.0);
        animatingImageView2.opaque = YES;
        animatingImageView2.layer.transform = transformblank;
    }
    [UIView animateWithDuration:self.transitionDuration animations:^{
        animatingImageView1.frame = [firstToView.superview convertRect:firstToView.frame toView:containerView];
        animatingImageView2.frame = [firstToView.superview convertRect:firstToView.frame toView:containerView];
        if (self.operation == UINavigationControllerOperationPush) {
            
            animatingImageView2.layer.transform = transformblank;
        } else {
            animatingImageView2.layer.transform = CATransform3DIdentity;
        }
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
        toView.alpha = 1;
        fromView.alpha = 1;
        secondFromView.alpha = 1;
        secondToView.alpha = 1;
        if (self.operation == UINavigationControllerOperationPush) {
            firstToView.alpha = 0;
        }else{
            
        }
        [animatingImageView1 removeFromSuperview];
        [animatingImageView2 removeFromSuperview];
    }];
}
#pragma mark - edge back gesture handling

- (void) handleEdgePan:(UIScreenEdgePanGestureRecognizer *)gr
{
    CGPoint point = [gr translationInView:gr.view];
    
    switch (gr.state) {
        case UIGestureRecognizerStateBegan:
            self.interactive = YES;
            [self.navigationController popViewControllerAnimated:YES];
            break;
        case UIGestureRecognizerStateChanged: {
            CGFloat percent = point.x / gr.view.frame.size.width;
            self.shouldCompleteTransition = (percent > 0.25);
            
            [self updateInteractiveTransition: (percent <= 0.0) ? 0.0 : percent];
            break;
        }
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
            if (!self.shouldCompleteTransition || gr.state == UIGestureRecognizerStateCancelled)
                [self cancelInteractiveTransition];
            else
                [self finishInteractiveTransition];
            self.interactive = NO;
            break;
        default:
            break;
    }
}

#pragma mark - UINavigationControllerDelegate

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController *)fromVC
                                                 toViewController:(UIViewController *)toVC {
    if (!navigationController) {
        return  nil;
    }
//    if ([toVC isKindOfClass:[ZMYReadViewController class]]||[fromVC isKindOfClass:[ZMYReadViewController class]]) {
//        self.transitionDuration = 0.8;
//    }else{
//        self.transitionDuration = 2.0;
//        return nil;
//    }
    self.operation = operation;
    if (![fromVC conformsToProtocol:@protocol(ZoomTransitionProtocol)] ||
        ![toVC conformsToProtocol:@protocol(ZoomTransitionProtocol)])
    {
        return nil;
    }
    
    return self;
}

- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                         interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
    if (self.isInteractive) {
        return self;
    }
    return nil;
}

@end
